home *** CD-ROM | disk | FTP | other *** search
- Path: xanth!cs.odu.edu!Amiga-Request
- From: Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator)
- Newsgroups: comp.sources.amiga
- Subject: v90i054: uucp 1.03D - unix compatible uucp/mail/news system, Part10/16
- Message-ID: <11293@xanth.cs.odu.edu>
- Date: 4 Feb 90 02:38:27 GMT
- Sender: tadguy@cs.odu.edu
- Reply-To: overload!dillon (Matt Dillon)
- Lines: 1808
- Approved: tadguy@cs.odu.edu (Tad Guy)
- X-Mail-Submissions-To: Amiga@cs.odu.edu
-
- Submitted-by: overload!dillon (Matt Dillon)
- Posting-number: Volume 90, Issue 054
- Archive-name: unix/uucp-1.03d/part10
-
- #!/bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 10 (of 16)."
- # Contents: src/dmail/dmail.help src/sendmail/sendmail.c
- # Wrapped by tadguy@xanth on Sat Feb 3 20:51:17 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'src/dmail/dmail.help' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/dmail/dmail.help'\"
- else
- echo shar: Extracting \"'src/dmail/dmail.help'\" \(23627 characters\)
- sed "s/^X//" >'src/dmail/dmail.help' <<'END_OF_FILE'
- X
- X'help TOPIC' for more information on a command. Many commands take
- Xmessage numbers or message lists:
- X [msg] is an optionaly specified message number (usually the
- X operation is on the current message if no number is
- X specified)
- X <list> is an optionaly specified message list. Message lists
- X consists of number ranges of the form N -N N- or N-N, and
- X keywords (help keywords)
- X
- X
- XOTHER HELP AVAILABLE (in addition to the commands):
- X pager sendmail tilde header newmail keywords enviroment
- X
- XDMAIL written by Matthew Dillon, U.C. Berkeley -UCF
- X
- X(C)Copyright 1985-1989 by Matthew Dillon
- X
- X.pager
- Xset page [rows/command]
- X
- X 'page' is a SET variable which determines the type of paging list and
- Xdisplay commands will use. If not defined, no filter is used. If a numerical
- Xvalue (i.e. 24) is specified, the page length will be set to that value and
- Xa rather stupid, simple internal paging routine will be used. If the
- Xvariable is set to an alpha-numeric string, output will be piped through
- Xthat filter. For instance:
- X
- X unset page -no paging
- X set page more -use more filter
- X set page page -use 'page' filter
- X set page > x -redirect to a file (be careful)
- X set page 24 -use internal paging, page length 24 rows.
- X
- X For internal paging, use <return> to continue, or your INTR
- Xcharacter to break out. Note that if you have paging set to a program,
- Xresponse time may be slower because dmail must execute that program.
- X
- X.sendmail
- Xset sendmail sendmail-path
- X
- X Inform DMAIL as to where the sendmail program is. The default
- X(variable unset) is /usr/lib/sendmail. This variable is useful only for
- Xthose of us who like to hack-up our own sendmail.
- X
- X.tilde
- X~ ~user directory expansion
- X
- X In all expressions except those within double quotes, the tilde
- X`~` will be expanded to either your home directory, or the directory of
- Xa specified user, depending. Note that '*' and '?' are not expanded by
- XDMAIL, though they will be by any shell commands you execute.
- X
- X It is probably a good idea to use ~ in any aliases, etc... in case
- Xyou change directories using the 'cd' command.
- X
- X alias resource source ~/.dmailrc -example using ~
- X
- X.header
- Xset header filepath
- X
- X Set the location of your header file, which will appended to the
- Xscratch mail file before you are placed in the editor (usually vi).
- X
- X set header ~/.header -set header file to ~/.header
- X unset header -no header file
- X
- X.newmail
- XWhen new mail comes in:
- X
- X Whenever newmail arrives, it will be automatically incorporated into
- Xa running DMAIL. However, to see it, you must 'select all' (or select on
- Xanything that would include it).
- X
- X.keywords
- X.range
- X.message
- XKEYWORDS, MESSAGE LISTS
- X
- X Many commands in DMAIL require a range of messages be given. A Range
- Xconsists of message numbers (3 4 5), message ranges (1-45 -9 9-), and
- Xkeywords. Keywords select certain messages from the entire SELECTED list:
- X
- X all -All messages
- X tag -All TAGGED messages
- X mark -All MARKED (read) messages
- X deleted -All DELETED messages
- X written -All WRITTEN messages
- X untag -All messages NOT TAGGED
- X unmark -All messages NOT MARKED (i.e. read)
- X undeleted -All messages NOT DELETED
- X unwritten -All messages NOT WRITTEN
- X
- X Only the first three letters need be specified. For instance, the
- X'all' keyword selects all the messages currently selected. You could select
- Xon some subject, say, and then 'delete all'.
- X
- X The message number 0 refers to the last message. the 'undeleted'
- Xkeyword exists only for completeness; you will probably never use it.
- X
- X.ver
- X.version
- XVER
- X
- X returns the version number.
- X
- X.if
- X.else
- X.endif
- XIF [!]variable
- XELSE
- XENDIF
- X
- X Conditionals. Example:
- X
- X if verbose
- X .... do stuff if the variable exists
- X else
- X ... do stuff if the variable does not exist
- X endif
- X if !page; echo no page variable; endif
- X
- X.nobreak
- X.breakok
- XNOBREAK
- XBREAKOK
- X
- X Disable or Enable your INTR key. This command is stackable, thus
- Xthere is no problem with recursive aliases which use it. Be careful that
- Xyou match any NOBREAK to a BREAKOK, or you may accidently put yourself into
- XNOBREAK mode (and a single BREAKOK may not fix it because it's stackable).
- X
- X A good example would be a command which needs the page variable set
- Xfor the duration... say an alias to TYPE to a file:
- X
- Xalias file "%_a nobreak; set _b $page; set page cat > $_a; type; set page $_b; unset _b; breakok"
- X
- X You can see that if the user were to hit his INTR character at the
- Xwrong time, the page variable would be incorrectly set. The nobreak/breakok
- Xcommands fix this problem. For simplicity, most people don't bother with
- Xbreak/nobreak, as it clutter's aliases up.
- X
- X.delete
- XDELETE <message list>
- X
- X Mark the specified messages for deletion. They will no longer show up
- Xon LISTings, (gaps will appear in message numbering). However, you can
- Xstill TYPE them, if you remember the message number, and you can always
- XUNDELETE them. Remember that the particular message # you've deleted
- Xmay be different if you change the SELECT parameters. For example,
- Xmessage #3 selecting 'To' & 'foo' may actually be message #45 when you
- Xare selecting ALL (see SELECT). Upon a QUIT, messages marked for
- Xdeletion are actually deleted from the mail file.
- X
- X.undelete
- XUNDELETE <message list>
- X
- X UNDELETES messages. Without arguments, UNDELETE will
- Xrestore the last message you deleted. Specifying 'all' (undelete all), will
- Xundelete any deleted messages in the currently selected message list.
- X
- X.header
- XHEADER [message]
- X
- X Display the entire header of a message. This does not cause the
- Xmessage to be marked 'read'. TYPE, on the other hand, only displays
- Xheader information specified by SETLIST.
- X
- X.type
- XTYPE [message]
- X
- X Type the text of a message. Only header fields defined by SETLIST
- Xare displayed. Otherwise, only the text is displayed. This marks
- Xthe particular message as 'read', and also makes that message the
- Xcurrent message.
- X
- X.echo
- XECHO [string]
- X
- X Echo the given string onto the screen.
- X
- X.go
- XGO #
- X go to a message, don't type it out or anything. Remember that you
- Xcan go to the last message by using the message # 0. By placing a keyword
- X(help range), you can go to the first TAGGED message, etc...
- X
- X.reply
- X.Reply
- XREPLY
- X
- X Reply to the current letter. There are two forms of 'reply'. The
- Xfirst does not include the senders original letter, the second does.
- XIn both cases, Dmail will place you in VI, with the To:, Cc:, and
- Xsubject lines filled out. The second form is 'Reply', with an
- Xupper case 'R'. This form includes the sender's message shifted to
- Xthe right with '>'s on the left hand side. See FORWARD for another
- Xmethod of replying to mail.
- X
- X In any case, you may get the sender's letter by reading the file '#'
- Xfrom VI. That sequence would be ':r\\#'
- X
- X See MAIL for more information on VI
- X
- X.forward
- XFORWARD [user user user....]
- X
- X Forward the current message to a list of users. The sender's
- Xentire message is placed in the text portion. The To: field will
- Xcontain the user's named above, and the Subject: field will contain
- Xa 'Fo:' (you append your own subject)
- X
- X See MAIL for more information on VI
- X
- X.mail
- XMAIL [user user user user...]
- X
- X Mail to [users]. You are given a VI to work from, and may modify
- Xany of the header fields. the From: field is inserted automatically
- Xby SENDMAIL, but you can overide it if you wish.
- X
- X Quitting out of VI without writing the output file will cause an
- Xabort, and no mail will be sent. Additionaly, you may use the 'vibreak'
- Xvariable to enable your INTR character (usually CTL-C) to break you out of
- XVI.
- X
- X When modifying the users list in To and Cc fields, remember that
- Xthey should be all comma delimited, or none comma delimited.
- X
- X.select
- XSELECT ALL
- XSELECT Field match match match match...
- XSELECT Field !match
- XSELECT Field match match match , Field match , .....
- X
- X Select what you want to look at. Select will take the field header
- Xyou supply and attempt to match arguments with that field in the mail
- Xfile. You can then work on the selected material as if the rest of
- Xyour mail didn't exist. For instance, 'select To dillon', will select
- Xall messages addressed to you. Note that case is checked for the
- XFIELD-HEADER, but not for arguments, so the latter will also find
- Xanything addressed to Dillon or DILLON. You only have to give a
- Xpartial match, so 'select To di' would work just as well.
- X
- X Select then, allows you to quickly find what you want even though
- Xyou may have 12000 messages (though it may take a while with that many)
- XYou may also specify what you DON'T want to select on:
- X
- X select To !foo
- X
- Xwill select all letters not addressed to 'foo'. You may select on any
- Xfield you wish. At any time, you may say 'select ALL' to select the
- Xentire message list. Use RESELECT to select on the current message
- Xlist. SELECT always selects from the entire message-list
- X
- X select Cc hack , To hack
- X
- Xwill select any mail with Cc or To fields containing hack. You may
- Xhave as many comma operators as you wish. The comma must be a field
- Xof its own (spaces on either side... will be fixed in a later version)
- X
- X.reselect
- XRESELECT ALL
- XRESELECT Field match match match match...
- XRESELECT Field !match
- X
- X SEE SELECT. Reselect allows you to CONTINUE to narrow down a topic
- Xor whatever. It will select on the current message list (which you have
- Xalready narrowed down with SELECT or RESELECT).
- X
- X.defer
- XDEFER
- X
- X Deselects any marked messages .. messages marked as 'read'. This is
- Xas if you did a RESELECT on all unread messages in the current select field.
- XThus, the messages will be renumbered. To see these messages again, you must
- Xuse SELECT.
- X
- X.rlist <num>
- XRLIST <num> -<num> > 0 (next N), < 0 (prev N).
- XRLIST -Lists next 20 (or previous 20 if near the end)
- X
- X Relative list. See LIST for details of the list command. This
- Xcommand will display the next <num> messages beginning at the current
- Xmessage. If <num> is negative, it displays the previous 20 ending at
- Xthe current message. If there are not enough messages remaining in the
- Xforward or reverse direction, it lists in the opposite direction to try
- Xto bring the total messages listed to <num>
- X
- X.list
- XLIST <message list>
- XLIST -Lists all selected messages
- X
- X Display header information on a message as specified by SETLIST,
- Xin a one line per message format. The default lists ALL messages.
- X
- XLeftword flags: r -indicates message has been read. Message will be
- X moved to the destination file on QUIT
- X > -indicates message is the current message
- X w -indicates message has been written to a file.
- X Message will be deleted from source file on QUIT
- X T -indicates message has been taged by the user
- X
- X.next
- XNEXT
- X
- X Execute TYPE or HEADER for the next message, depending on which of
- XTYPE or HEADER was last executed by you
- X
- X._next
- X_NEXT
- X
- X Go to next message, do not print it out.
- X
- X.back
- XBACK
- X
- X Execute TYPE or HEADER for the previous message, depending on which
- Xof TYPE or HEADER was last executed by you
- X
- X._back
- X_BACK
- X
- X Go to previous message, do not print it out.
- X
- X.db
- XDB
- X Delete the current message, type (or header) the previous message.
- XThis command could not be implemented with "del;prev" due to a special case
- Xwhen one is on the last message.
- X
- X.dt
- XDT
- X Delete current message, type (or header) next message. This command
- Xwill warn you when you reach the end of the message list.
- X
- X References: DELETE and NEXT
- X
- X.enviroment
- XENVIROMENT VARIABLE ACCESS
- X
- X Access may be gained to enviroment variables by using $$ instead of
- X a single $. For example: echo $$USER
- X
- X 'help dmail' for command line options,
- X 'help set' for description of special variables
- X
- X.set
- XSET [variable [string]]
- X
- X see 'enviroment' for enviroment variables
- X
- X With no arguments, SET prints out all currently active variables.
- XNote that this variable list is a different list than the ALIAS list. With
- Xone argument, the specified variable is displayed if it exists, or created
- Xif it doesn't. With more than one argument, the specified variable is set
- Xto the specified string. Variables may be references on the command line by
- X$variable . The variable's contents will replace the reference. Unlike
- Xaliases, however, variable substitutions may take place anywhere on the
- Xcommand line rather than substitute just the command name. Note also that
- Xif you use a $ substitution for an argument of a command, the entire
- Xvariable's contents is ONE argument (i.e. if a = "b c d", and you say
- Xsomething like: 'unset $a', it would attempt to unset a single variable
- Xwhos name is "b c d".
- X
- X There are several reserved SET variables, which define options in
- XDMAIL. Changing these will modify the option:
- X
- X page set paging on or to a specific command (i.e. more)
- X sendmail set the path to the sendmail program
- X vibreak enable your INTR character even when in VI.
- X verbose reflects verbose option to sendmail
- X comlinemail set when dmail executed w/ command line mailing list
- X header header file to append to any messages you send.
- X ask ask what to do after vi'ing mail
- X archive file to archive any mail you send out in.
- X _headchar string used to precede included text, default ">"
- X replyfields fields to search to find the reply path
- X
- X page
- X
- X This variable determines what kind of paging is used for LIST,
- X TYPE, and HEADER commands. If the variable does not exist, paging
- X is turned off. If set to null (no string), an internal paging
- X routine is used. If set to a value, an internal paging routine is
- X used using the value as the page length. the 'page' variable can
- X also be set to a command, such as 'more' or 'page', in which case,
- X the output is piped through those commands:
- X
- X set page Turn paging on (internal page routine)
- X set page 25 Internal page routine... 25 rows/screen
- X set page more Use 'more' command to pipe output through
- X set page page Use 'page' command to pipe output through
- X
- X you could also conceviably say: 'set page cat > x', or
- X 'set page cat | lpr', but be very careful.
- X
- X sendmail
- X
- X This variable will redirect DMAIL as to where the mailer program
- X is. The mailer program must be compatible with /usr/lib/sendmail
- X which is the default used if the 'sendmail' variable isn't set
- X to anything:
- X
- X set sendmail bin/mysendmail
- X
- X vibreak
- X
- X This variable, when set, allows the INTR character to abort a
- X reply, mail, or forward command. Otherwise, if this variable is
- X not present, INTR will not abort the above commands.
- X
- X verbose
- X
- X This variable, when set, causes the -v flag to be sent to
- X sendmail. In addition, DMAIL will wait for sendmail to complete
- X before returning your prompt.
- X
- X comlinemail
- X
- X This variable is set when dmail is invoked with a command line
- X user list (e.g. dmail charlie mary mark). Usually, one uses
- X this variable in an IF construct. A good example would be that
- X you may usually CD to a mail directory, but you don't want to
- X CD when dmail is run with a command line user-list:
- X
- X if !comlinemail
- X cd ...
- X
- X alternate definition: The comlinemail variable will NOT be set
- X if dmail is in interactive mode.
- X
- X header
- X
- X The file specified by this variable will be appended onto the temp
- X vi files in reply and mail. The file is appended before you go into
- X vi, so when you do, what you see is still what you get.
- X
- X ask
- X
- X If set, dmail will ask you what to to (quit, send, re-edit) after you
- X leave the editor when sending mail. If not set, the mail is sent as
- X soon as you leave the editor (unless you didn't write anything).
- X
- X archive
- X
- X If set (to a file name), any mail you send out (mail/reply/etc...)
- X will be archived to this file. Usually, you provide a fully
- X specified path so cd's won't effect the file location.
- X
- X _headchar
- X
- X This string is prepend to any included text when you do an upper-case
- X reply (R) command.
- X
- X replyfields
- X
- X This string holds a list of fields which are searched for to
- X determine which one to use in the To: field of your reply. If
- X this variable does not exist or none of the specified fields could
- X be found, the 'From ' (not From:) mail header will be used. The
- X search ends at the first field found. Example:
- X
- X set replyfields "Reply-To: From:"
- X
- X.replyfields
- XSET replyfields "field1 field2 ..."
- X
- X This string holds a list of fields which are searched for to
- X determine which one to use in the To: field of your reply. If
- X this variable does not exist or none of the specified fields could
- X be found, the 'From ' (not From:) mail header will be used. The
- X search ends at the first field found. Example:
- X
- X set replyfields "Reply-To: From:"
- X
- X.>
- XSET _HEADCHAR "string"
- X
- X see SET. The _headchar variable determines the string prepending all
- X included text when you do an upper-case reply (R) command.
- X
- X.archive
- XSET ARCHIVE file
- X
- X if the archive variable is set to a file path, any mail you send out
- X will automatically be appended to that file. Dmail pre-pends a
- X "From ", so it is compatible with /bin/mail and so that you can
- X dmail -f your archive file. Additionaly, a "Date: " field is
- X pre-pended so you know when you sent the message. example:
- X
- X set archive ~/Dmail/arch
- X
- X since your .dmailrc is sourced even when you "dmail user .." from
- X your csh, putting the above line in your .dmailrc will turn on
- X archiving whenever you use dmail to send mail, command line or
- X dmail prompt.
- X
- X if unset or set to nothing, no archive is made.
- X
- X.ask
- XSET ASK
- X
- X if the 'ask' variable is set (set ask), dmail will ask you what to do
- X when you are finished editing mail rather than send it immediately.
- X (see 'help set')
- X
- X.alias
- XALIAS [variable [string]]
- X
- X Create an alias for a command. With no arguments, ALIAS will display
- Xall active aliases. With one argument, a particular alias is displayed (if
- Xit exists), or defined (if it did not previously exist). With more than one
- Xargument, the particular alias is set to the string list specified.
- X
- Xalias
- Xalias hack "select From hacker , To hacker , Cc hacker"
- Xalias bye quit
- Xalias stuff "setlist 60 To ; list"
- X
- X Usually, any arguments following the alias are appended to the
- Xexpansion. However, you can place such arguments inside the alias somewhere
- Xby using the following construction:
- X
- Xalias myecho "%var echo $var ; list"
- X
- Xmyecho hello there ---> echo hello there ; list
- X
- X to unalias an alias, use the UNALIAS command.
- X
- X.unset
- X.unalias
- XUNSET var var var...
- XUNALIAS var var var...
- X
- X Eradicate variables or aliases from memory.
- X
- X.setlist
- XSETLIST [-s] [columns] Field [columns] Field ...
- X
- X -s prevents display of the list.
- XSet the list format used for LIST and TYPE. The optional [columns]
- Xindicates how many columns to allocate for the Field specified. The
- XField can be a partial match. However, case is observed:
- X
- Xsetlist 18 Fro 38 Sub 10 To 0 Dat
- X
- X18 columns for the From: field, etc... when TYPEing messages, the
- X[columns] is ignored, and each field is printed in its entirety.
- XNote that 0 columns have been allocated for the Date: field.
- XTherefore, the Date: field will not show up on the LIST command,
- Xbut will show up in the TYPE command.
- X
- X.cd
- XCD PATH
- X
- X cd, as in csh. Changes your base directory. You can use
- X the shell escape '! pwd' to get your current working directory.
- X
- X.source
- XSOURCE file
- X
- X Source a file. The file is read in an executed in sequence.
- X
- X.preserve
- XPRE <message list>
- X
- X PRESERVE messages. A message is MARKED if it has been read (has an 'r'
- Xflag from the LIST command). Marked messages are moved from your readfile
- Xinto your outfile upon a QUIT. If you are reading and writing to the same
- Xfile (i.e. from your mbox to your mbox), the 'r' flag has no effect.
- X
- X However, if you are reading from your spool file, and want to keep
- Xread messages in your spool (that is, not move them to your mbox), you want
- Xto PRESERVE them. This command simply unmarks them, so they appear not to
- Xhave been read.
- X
- X.mark
- XMARK <message list>
- X
- X Mark messages specified as being already 'read'. Remember that if
- Xyou executed DMAIL without a -f option, any message 'read' at the time
- Xyou quit will be moved to MBOX (or file specified by -o)
- X
- X.tag
- X.untag
- XTAG <list>
- XUNTAG <list>
- X
- X The TAG command allow you to flag any message. You can tag a set of
- Xmessages, then reference them all at once. For instance, if you tag
- Xinteresting messages as you glance at them, you may then write them all
- Xto a file by 'write filename tag', or list them with 'list tag'.
- XAlternately, you could delete all your taged messages with a single delete
- Xcommand 'delete tag'. The 'tag' operand works in the same way as the 'all'
- Xoperand, except it works only on taged messages.
- X
- X UNTAG will untag a particular message in your message list. For
- Xinstance, to untag any taged messages in the entire message list, you would:
- X
- X select all
- X untag all OR untag tag
- X
- X Note that 'untag all' and 'untag tag' have the same effect.
- X
- X.write
- XWRITE file <message list>
- X
- X Write the given messages or the current message to a file. The file
- Xfile is appended to. Remember that you may specify 'all' to write
- Xall messages in the current select field to the file. Messages will be
- Xmarked as having been writen, and will be deleted from the mail file
- Xwhen you 'quit'. However, you may cause them to be kept in the mail
- Xfile by UNdeleting the messages (i.e. undelete all)
- X
- X You can also TAG the messages you want to write, and say
- X'write file tag' to write to the file all taged messages.
- X
- X.!
- X! [shell command]
- X
- X Give yourself a shell or execute a shell command. The shell forked
- Xis that specified by your SHELL enviroment variable, or /bin/sh if there is
- Xno SHELL enviroment variable.
- X
- X.x
- X.exit
- XX (EXIT)
- X
- X EXIT out of DMAIL without changing any files. Usually, one exits
- Xwith QUIT, which would cause deleted messages to disappear, and TYPEd
- Xmessages to go to MBOX (if you did not use the -f option with DMAIL).
- X
- X If your outfile is the same as your infile, reading a message does
- Xnot effect anything.
- X
- X.quit
- XQUIT
- X
- X Quit out of DMAIL. Delete any messages that were marked for deletion
- Xand if you executed DMAIL on /usr/spool/mail/ (default), any mail
- Xmarked 'read' will be placed in MBOX in your home directory
- X
- X.xswitch
- X.qswitch
- XXSWITCH fromfile [tofile]
- XQSWITCH fromfile [tofile]
- X
- X Switch to a different set of files. XSWITCH doesn't modify your
- Xold from and to files before switching, QSWITCH works as if you had QUIT
- Xstuff before switching to another set of files.
- X
- X If no [tofile] is specified, the new tofile will be the same as the
- Xfromfile you specify.
- X
- X.help
- X.?
- XHELP [topic]
- X
- X Give me help on a topic
- X
- X.dmail
- XCOMMAND LINE OPTIONS FOR DMAIL
- X
- X dmail -O [-l rcfile] -f [file] -o [file] -F field -F field -F field ...
- X
- X Default conditions:
- X Home directory gotten from password entry
- X User gotten from password entry
- X Visual editor set to /usr/ucb/vi
- X
- X VI BREAKOUT enabled
- X READ file is /usr/spool/mail/$USER
- X WRITE file is $HOME/mbox
- X From:, To:, and Subject: fields will be loaded into memory.
- X
- X HOME enviroment variable becomes home directory
- X USER enviroment variable becomes user name
- X VISUAL enviroment variable becomes editor used
- X
- X -O Go into interactive mode, even if there is no
- X mail to read.
- X
- X -f [from file] Specify spool file to get mail from. If no file
- X Argument is given, $HOME/MBOX is used.
- X
- X -o [to file] Specify file to write to, If no Argument
- X is given, $HOME/.MBOX is used. Note that
- X the default without -o is $HOME/MBOX
- X
- X -f -o With no file arguments causes both READ and
- X WRITE files to be $HOME/.MBOX
- X
- X -F field Append this field to those which will be
- X used on initial load. If, During usage of the
- X program you specify a field which is not in
- X memory, DMAIL will be forced to re-load the
- X entire spool file, which can take a long time
- X if you have more than 64K in the file
- X
- X -l rcfile Use this as the rc file rather than .dmailrc
- X
- X -L Do not source the rc file on boot
- X
- X
- END_OF_FILE
- if test 23627 -ne `wc -c <'src/dmail/dmail.help'`; then
- echo shar: \"'src/dmail/dmail.help'\" unpacked with wrong size!
- fi
- # end of 'src/dmail/dmail.help'
- fi
- if test -f 'src/sendmail/sendmail.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/sendmail/sendmail.c'\"
- else
- echo shar: Extracting \"'src/sendmail/sendmail.c'\" \(22055 characters\)
- sed "s/^X//" >'src/sendmail/sendmail.c' <<'END_OF_FILE'
- X
- X/*
- X * SENDMAIL / RMAIL
- X *
- X * (C) Copyright 1989-1990 by Matthew Dillon, All Rights Reserved.
- X *
- X * SENDMAIL <file -f from -t to -s subject -c cc -b bcc -r
- X * RMAIL user
- X *
- X * Example: Sendmail <datafile -froot
- X *
- X * From: line is automatically added but can be overriden by a From:
- X * header in the file. stdin is made up of a list of headers, a blank
- X * line, and then data until EOF.
- X *
- X * the -r option tells sendmail that this is incomming mail.
- X * If av[0] begins with an 'r' for RMail instead of an 's' for
- X * Sendmail, then the rmail argument format is used (rmail user),
- X * as well as forcing -r.
- X */
- X
- X#include <exec/types.h>
- X#include <exec/lists.h>
- X#include <proto/all.h>
- X#include <stdio.h>
- X#include <stdlib.h>
- X#include <string.h>
- X#include <log.h>
- X#include <config.h>
- X#include <time.h>
- X#include <pwd.h>
- X#include <string.h>
- X#include "/version.h"
- X
- X#define RCVR_UUCP 1
- X#define RCVR_SENDMAIL 2
- X
- XIDENT(".03");
- X
- Xtypedef struct List LIST;
- Xtypedef struct Node NODE;
- X
- Xchar *UserName;
- Xchar *NodeName;
- Xchar *DomainName;
- Xchar *TimeZoneName; /* All caps, ex: PST */
- Xchar *DefaultNode; /* for addr formats we don't understand */
- XLIST RecvList; /* Received: */
- XLIST FromList; /* last one rules */
- XLIST ToList; /* To: */
- XLIST CcList; /* Cc: */
- XLIST BccList; /* Bcc: */
- XLIST XccList; /* list of actual mail to be sent */
- XLIST SubjList; /* Subject: */
- XLIST HdrList; /* other headers not specifically parsed */
- Xchar ScrBuf[1024];
- Xchar ScrBuf2[1024];
- Xchar TempFileBuf[256];
- Xint Seq; /* UUCP sequence no */
- Xchar ROpt; /* Receive-Mail flag */
- Xstatic char OrigFromLine[512];
- Xstatic char FromLine[512]; /* 'From ' line, if ROpt */
- X
- Xchar *TmpFileName();
- Xchar *atime();
- Xvoid PostPend();
- Xvoid MakeToFixNode();
- Xvoid MakeToAddrNode();
- Xvoid ToFixup();
- Xvoid FromFixup();
- Xvoid DumpHeaderInfo();
- Xvoid DumpHeader();
- Xvoid DumpCombineHeader();
- Xvoid IntegrateHeader();
- Xvoid Usage();
- XFILE *SendMailTo();
- XFILE *OneMailTo();
- XFILE *OneMailToUUCP();
- XFILE *OneMailToUser();
- XFILE *OneMailToFile();
- XFILE *OneMailToPipe();
- XNODE *FindHeader();
- XNODE *MakeNode();
- X
- XCXBRK()
- X{
- X return(0);
- X}
- X
- Xvoid
- XUsage()
- X{
- X printf(
- X "Sendmail -f user [-t address -c address -b address -s subject -r]\n"
- X "RMail user\n"
- X );
- X}
- X
- Xvoid
- Xmain(ac, av)
- Xchar *av[];
- X{
- X short isRMail = 0;
- X short isSendMail = 1;
- X FILE *fi;
- X
- X NewList(&RecvList);
- X NewList(&FromList);
- X NewList(&ToList);
- X NewList(&CcList);
- X NewList(&BccList);
- X NewList(&XccList);
- X NewList(&SubjList);
- X NewList(&HdrList);
- X
- X UserName = FindConfig("UserName");
- X if (UserName == NULL) {
- X puts("Sendmail: UserName not in UULIB:Config!");
- X exit(1);
- X }
- X NodeName = FindConfig("NodeName");
- X if (NodeName == NULL) {
- X puts("Sendmail: NodeName not in UULIB:Config!");
- X exit(1);
- X }
- X DomainName = FindConfig("DomainName");
- X if (DomainName == NULL) {
- X puts("Sendmail: DomainName not in UULIB:Config! using .UUCP");
- X DomainName = ".UUCP";
- X }
- X DefaultNode = FindConfig("DefaultNode");
- X TimeZoneName = FindConfig("TimeZone");
- X
- X LoadAliases();
- X
- X {
- X char *ptr = av[0] + strlen(av[0]);
- X
- X /*
- X * Skip path
- X */
- X
- X while (ptr >= av[0] && *ptr != ':' && *ptr != '/')
- X --ptr;
- X ++ptr;
- X
- X if (*ptr == 'r' || *ptr == 'R') {
- X isRMail = 1;
- X isSendMail = 0;
- X }
- X }
- X
- X if (isRMail) {
- X char *addr = (ac == 2) ? av[1] : "Mailer-Daemon";
- X
- X MakeNode(&BccList, addr);
- X UserName = "postmaster"; /* XXX */
- X ROpt = 1; /* no header processing */
- X }
- X if (isSendMail) {
- X short i;
- X char *arg;
- X for (i = 1; i < ac; ++i) {
- X arg = av[i];
- X if (*arg != '-')
- X Usage();
- X switch(arg[1]) {
- X case 'f':
- X UserName = av[i+1];
- X sprintf(ScrBuf, "%s@%s%s", av[i+1], NodeName, DomainName);
- X MakeNode(&FromList, ScrBuf);
- X ++i;
- X break;
- X case 't':
- X MakeNode(&ToList, av[++i]);
- X break;
- X case 'c':
- X MakeNode(&CcList, av[++i]);
- X break;
- X case 'b':
- X MakeNode(&BccList, av[++i]);
- X break;
- X case 's':
- X MakeNode(&SubjList, av[++i]);
- X break;
- X case 'r':
- X ++ROpt;
- X break;
- X default:
- X Usage();
- X }
- X }
- X }
- X
- X /*
- X * Read headers from input file. Headers are not necessarily
- X * contained on a single line. Maximum 4096 chars per header.
- X */
- X
- X if (ROpt) {
- X fgets(ScrBuf, sizeof(ScrBuf), stdin);
- X strcpy(OrigFromLine, ScrBuf);
- X if (strncmp(ScrBuf, "From ", 5) != 0) {
- X ulog(-1, "Receive mail, expected 'From ', got %s", ScrBuf);
- X }
- X strcpy(FromLine, "From ");
- X PostPend(ScrBuf + 5, 1);
- X
- X while (fgets(ScrBuf, sizeof(ScrBuf), stdin) && strncmp(ScrBuf, ">From ", 6) == 0) {
- X strcpy(OrigFromLine, ScrBuf + 1);
- X PostPend(ScrBuf + 6, 1);
- X }
- X strcpy(ScrBuf2, OrigFromLine + 5);
- X PostPend(ScrBuf2, 0);
- X } else {
- X ScrBuf[0] = '\n';
- X fgets(ScrBuf, sizeof(ScrBuf), stdin);
- X }
- X {
- X static char Hdr[4096];
- X short i = 0; /* index into Hdr */
- X
- X while (ScrBuf[0] != '\n') {
- X char *ptr = ScrBuf;
- X while (*ptr && *ptr != ' ' && *ptr != 9 && *ptr != ':')
- X ++ptr;
- X if (*ptr == ':') { /* found new header */
- X if (i) /* Dump old header */
- X IntegrateHeader(Hdr, i);
- X strcpy(Hdr, ScrBuf);
- X i = strlen(Hdr);
- X } else { /* append to existing header */
- X if (i == 0)
- X puts("Expected a Header!");
- X strcpy(Hdr + i, ScrBuf);
- X i = i + strlen(Hdr + i);
- X }
- X
- X if (fgets(ScrBuf, sizeof(ScrBuf), stdin) == NULL)
- X ScrBuf[0] = '\n';
- X }
- X if (i)
- X IntegrateHeader(Hdr, i);
- X
- X if (ScrBuf[0] != '\n') {
- X puts("sendmail: no mail");
- X exit(1);
- X }
- X }
- X
- X /*
- X * Parse & fixup each To:, Cc:, and Bcc: field.
- X *
- X * From: we add the personal info arg from the password file
- X * To: we expand any aliases
- X */
- X
- X if (ROpt == 0)
- X FromFixup(&FromList);
- X if (ROpt) {
- X ToFixup(&BccList);
- X } else {
- X ToFixup(&ToList);
- X ToFixup(&CcList);
- X ToFixup(&BccList);
- X }
- X
- X /*
- X * If no Subject: field add a dummy one
- X */
- X
- X if (EmptyList(&SubjList))
- X MakeNode(&SubjList, "");
- X
- X if (EmptyList(&FromList)) {
- X sprintf(ScrBuf, "%s@%s%s", UserName, NodeName, DomainName);
- X MakeNode(&FromList, ScrBuf);
- X }
- X
- X fi = SendMailTo(&XccList, stdin);
- X if (fi && fi != stdin)
- X fclose(fi);
- X if (TempFileBuf[0])
- X remove(TempFileBuf);
- X UnLockFiles();
- X}
- X
- X/*
- X * Strips string and creates named node which is appended to the
- X * given list.
- X */
- X
- XNODE *
- XMakeNode(list, str)
- XLIST *list;
- Xchar *str;
- X{
- X NODE *node;
- X char *ptr;
- X
- X while (*str == ' ' || *str == 9)
- X ++str;
- X for (ptr = str + strlen(str); ptr >= str && (*ptr == ' ' || *ptr == 9); --ptr);
- X ++ptr;
- X *ptr = 0;
- X node = malloc(sizeof(NODE) + strlen(str) + 1);
- X node->ln_Name = (char *)(node + 1);
- X strcpy(node->ln_Name, str);
- X AddTail(list, node);
- X return(node);
- X}
- X
- X/*
- X *
- X */
- X
- Xvoid
- XMakeToFixNode(list, str, send)
- XLIST *list;
- Xchar *str;
- Xchar *send;
- X{
- X char *ptr;
- X short len;
- X short c;
- X void fixCallBack();
- X
- X while (str < send && (*str == ' ' || *str == 9))
- X ++str;
- X for (ptr = send - 1; ptr >= str && (*ptr == ' ' || *ptr == 9); --ptr);
- X ++ptr;
- X
- X len = ptr - str;
- X if (len < 0)
- X return;
- X
- X /*
- X * str[0..len-1]
- X */
- X
- X c = str[len];
- X str[len] = 0;
- X
- X if (ROpt) { /* disallow remote asking for special options */
- X ulog(-1, "Received mail for %s", str);
- X if (str[0] == '>' || str[0] == '<' || str[0] == '|' || str[0] == ':' || str[0] == '/') {
- X ulog(-1, "SendMail, bad user %s", str);
- X return;
- X }
- X }
- X
- X {
- X NODE *node = malloc(sizeof(NODE) + strlen(str) + 1);
- X
- X node->ln_Name = (char *)(node + 1);
- X strcpy(node->ln_Name, str);
- X AddTail(list, node);
- X }
- X
- X UserAliasList(str, fixCallBack); /* from lib/alias.c */
- X str[len] = c;
- X}
- X
- Xvoid
- XfixCallBack(user)
- Xchar *user;
- X{
- X NODE *node;
- X
- X if (user[0] == '<') {
- X FILE *fi = fopen(user + 1, "r");
- X char *buf = malloc(256);
- X
- X if (fi == NULL) {
- X ulog(-1, "Unable to open < file %s", user + 1);
- X return;
- X }
- X while (fgets(buf, 256, fi)) {
- X short i = 0;
- X short j;
- X while (buf[i] == ' ' || buf[i] == 9)
- X ++i;
- X if (buf[i] == 0 || buf[i] == '\n')
- X continue;
- X for (j = i; buf[j] && buf[j] != '\n' && buf[j] != ' ' && buf[j] != 9; ++j);
- X buf[j] = 0;
- X UserAliasList(buf, fixCallBack);
- X }
- X fclose(fi);
- X free(buf);
- X return;
- X }
- X
- X ulog(-1, "Sendmail, Sending mail to %s", user);
- X
- X if (user[0] == '\\')
- X ++user;
- X
- X node = malloc(sizeof(NODE) + strlen(user) + 1);
- X node->ln_Name = (char *)(node + 1);
- X strcpy(node->ln_Name, user);
- X AddTail(&XccList, node);
- X}
- X
- X
- X/*
- X * Integrates a header
- X */
- X
- Xvoid
- XIntegrateHeader(hdr, len)
- Xchar *hdr;
- Xshort len;
- X{
- X if (hdr[len-1] == '\n') /* strip trailing newline */
- X hdr[len-1] = 0;
- X
- X if (strncmp(hdr, "From:", 5) == 0) {
- X MakeNode(&FromList, hdr + 5);
- X return;
- X }
- X if (strncmp(hdr, "To:", 3) == 0) {
- X MakeNode(&ToList, hdr + 3);
- X return;
- X }
- X if (strncmp(hdr, "Cc:", 3) == 0) {
- X MakeNode(&CcList, hdr + 3);
- X return;
- X }
- X if (strncmp(hdr, "Bcc:", 4) == 0) {
- X MakeNode(&BccList, hdr + 4);
- X return;
- X }
- X if (strncmp(hdr, "Subject:", 8) == 0) {
- X MakeNode(&SubjList, hdr + 8);
- X return;
- X }
- X if (strncmp(hdr, "Received:", 9) == 0) {
- X MakeNode(&RecvList, hdr + 9);
- X return;
- X }
- X MakeNode(&HdrList, hdr);
- X}
- X
- X/*
- X * Adds (personal info) to FromList based on passwd entry or, if
- X * that is not available, from the Config entry 'RealName'.
- X */
- X
- Xvoid
- XFromFixup(list)
- XLIST *list;
- X{
- X char *wholeName = GetConfig("RealName", "Who Knows");
- X NODE *node;
- X NODE *nn;
- X LIST tmpList;
- X
- X NewList(&tmpList);
- X
- X while (node = RemHead(list)) {
- X /*
- X * FIXME. Fix getpwnam() and use pw_gecos entry.
- X */
- X nn = malloc(sizeof(NODE) + strlen(node->ln_Name) + strlen(wholeName) + 16);
- X nn->ln_Name = (char *)(nn + 1);
- X sprintf(nn->ln_Name, "%s (%s)", node->ln_Name, wholeName);
- X free(node);
- X AddTail(&tmpList, nn);
- X }
- X while (node = RemHead(&tmpList))
- X AddTail(list, node);
- X}
- X
- X/*
- X * Converts an unparsed list of names into a list of single address
- X * fields, removing any personal idents from the entries. These will
- X * be recombined after processing when the data file is written out.
- X *
- X * Also expands sendmail aliases (UULIB:Aliases) (HACK)
- X */
- X
- Xvoid
- XToFixup(list)
- XLIST *list;
- X{
- X NODE *node;
- X LIST tmpList;
- X
- X NewList(&tmpList);
- X
- X while (node = RemHead(list)) {
- X char *str = node->ln_Name;
- X char *ptr;
- X
- X while (*str) { /* breakup fields by newline or comma */
- X for (ptr = str; *ptr && *ptr != '\n' && *ptr != ','; ++ptr);
- X MakeToAddrNode(&tmpList, str);
- X str = ptr;
- X while (*str == '\n' || *str == ',' || *str == ' ' || *str == 9)
- X ++str;
- X }
- X free(node);
- X }
- X while (node = RemHead(&tmpList))
- X AddTail(list, node);
- X}
- X
- X/*
- X * Extracts a single name / address (comma or newline delimited)
- X * field and creates a new node.
- X */
- X
- Xvoid
- XMakeToAddrNode(list, str)
- XLIST *list;
- Xchar *str;
- X{
- X char *p1, *p2;
- X short ns = 0; /* non-whitespace encountered */
- X
- X for (p1 = str; *p1 && *p1 != ',' && *p1 != '\n'; ++p1) {
- X if (*p1 == '(') { /* addr (name) OR (name) addr */
- X if (ns) { /* addr (name) */
- X MakeToFixNode(list, str, p1);
- X } else {
- X while (*p1 && *p1 != ',' && *p1 != '\n' && *p1 != ')')
- X ++p1;
- X if (*p1 == ')') {
- X for (p2 = p1 + 1; *p2 && *p2 != ',' && *p2 != '\n'; ++p2);
- X MakeToFixNode(list, p1 + 1, p2);
- X }
- X }
- X return;
- X }
- X
- X if (*p1 == '<') { /* <addr> */
- X for (p2 = p1 + 1; *p2 && *p2 != ',' && *p2 != '\n' && *p2 != '>'; ++p2);
- X if (*p2 == '>')
- X MakeToFixNode(list, p1 + 1, p2);
- X return;
- X }
- X if (*p1 != ' ' && *p1 != 9)
- X ns = 1;
- X }
- X MakeToFixNode(list, str, p1);
- X}
- X
- X
- X/*
- X * Send mail to <recipeant>
- X *
- X * -Local mail
- X * -Machine path (UUCP)
- X */
- X
- XFILE *
- XSendMailTo(list, fi)
- XLIST *list;
- XFILE *fi;
- X{
- X NODE *node;
- X
- X for (node = list->lh_Head; node != (NODE *)&list->lh_Tail; node = node->ln_Succ)
- X fi = OneMailTo(node->ln_Name, fi);
- X return(fi);
- X}
- X
- XFILE *
- XOneMailTo(toaddr, rfi)
- Xchar *toaddr;
- XFILE *rfi;
- X{
- X short i;
- X char c;
- X static char Buf[256];
- X static char typeBuf[16];
- X static char classBuf[16];
- X static char addrBuf[128];
- X
- X if (toaddr[0] == '|') /* pipe through command */
- X return(OneMailToPipe(toaddr + 1, rfi));
- X if (toaddr[0] == '>') /* copy to file */
- X return(OneMailToFile(toaddr + 1, rfi));
- X
- X for (i = 0; c = toaddr[i]; ++i) {
- X if (c == '!' || c == '%' || c == '@' || c == ':')
- X break;
- X }
- X if (c == 0) /* local name */
- X return(OneMailToUser(toaddr, rfi));
- X
- X /*
- X * Non-Local mail
- X */
- X
- X i = ParseAddress(toaddr, Buf, strlen(toaddr));
- X if (DomainLookup(Buf, strlen(Buf), typeBuf, classBuf, addrBuf)) {
- X printf("type %s class %s addr %s\n", typeBuf, classBuf, addrBuf);
- X printf("buf %s\n", Buf);
- X
- X /*
- X * Note distinction between mail destination and mail forwarder.
- X * mail destination removes the first machine from the rmail line
- X * mail forwarder does NOT
- X */
- X
- X if (strcmpi(classBuf, "UU") == 0) {
- X if (strcmpi(typeBuf, "MD") == 0)
- X return(OneMailToUUCP(addrBuf, Buf + i + 1, rfi));
- X else
- X return(OneMailToUUCP(addrBuf, Buf, rfi));
- X } else {
- X ulog(-1, "Unsupported domain class: %s", classBuf);
- X printf("Unsupported domain class: %s\n", classBuf);
- X }
- X return(rfi);
- X } else {
- X ulog(-1, "Could not find domain for %s, no mail sent", Buf);
- X printf("Unable to send mail to %s\n", Buf);
- X return(rfi);
- X }
- X}
- X
- X
- XFILE *
- XOneMailToPipe(toaddr, rfi)
- Xchar *toaddr;
- XFILE *rfi;
- X{
- X FILE *fi;
- X char *ptr;
- X static long pos;
- X
- X if (TempFileBuf[0] == 0) {
- X strcpy(TempFileBuf, TmpFileName("T:pipe"));
- X fi = fopen(TempFileBuf, "w");
- X if (fi == NULL) {
- X ulog(-1, "Unable to open temp file %s for command: %s", TempFileBuf, toaddr);
- X return(rfi);
- X }
- X DumpHeaderInfo(fi, RCVR_SENDMAIL, 0, 1);
- X pos = ftell(fi);
- X while (fgets(ScrBuf, sizeof(ScrBuf), rfi))
- X fputs(ScrBuf, fi);
- X fclose(fi);
- X }
- X strcpy(ScrBuf, toaddr);
- X
- X ptr = toaddr;
- X if (strncmpi(toaddr, "run", 3) == 0) {
- X ptr += 3;
- X while (*ptr == ' ' || *ptr == 9)
- X ++ptr;
- X }
- X while (*ptr && *ptr != ' ' && *ptr != 9)
- X ++ptr;
- X
- X if (*ptr == 0)
- X strcat(ScrBuf, " ");
- X sprintf(ScrBuf + (ptr - toaddr + 1), "<%s %s", TempFileBuf, ptr);
- X if (Execute(ScrBuf, NULL, NULL) == 0)
- X ulog(-1, "Couldn't execute %s", ScrBuf);
- X
- X fi = fopen(TempFileBuf, "r");
- X if (fi) {
- X if (rfi != stdin)
- X fclose(rfi);
- X rfi = fi;
- X fseek(rfi, pos, 0);
- X } else {
- X ulog(-1, "Couldn't reopen temp '%s', mail failed!", TempFileBuf);
- X rfi = stdin;
- X }
- X return(rfi);
- X}
- X
- XFILE *
- XOneMailToUser(toaddr, rfi)
- Xchar *toaddr;
- XFILE *rfi;
- X{
- X sprintf(ScrBuf, "UUMAIL:%s", toaddr);
- X return(OneMailToFile(ScrBuf, rfi));
- X}
- X
- XFILE *
- XOneMailToFile(tofile, rfi)
- Xchar *tofile;
- XFILE *rfi;
- X{
- X FILE *fo;
- X static char DataFile[128];
- X long pos;
- X
- X strcpy(DataFile, tofile);
- X
- X LockFile(DataFile);
- X fo = fopen(DataFile, "a");
- X if (fo == NULL) {
- X strcpy(DataFile, "T:MailOverflow");
- X fo = fopen(DataFile, "a");
- X if (fo)
- X ulog(-1, "Could not append to %s, appending to %s", tofile, DataFile);
- X else
- X ulog(-1, "Can't append to anywhere! (%s)", tofile);
- X }
- X if (fo) {
- X DumpHeaderInfo(fo, RCVR_SENDMAIL, 0, 1);
- X pos = ftell(fo);
- X if (ROpt) {
- X if (fgets(ScrBuf, sizeof(ScrBuf), rfi))
- X fputs(ScrBuf, fo);
- X }
- X while (fgets(ScrBuf, sizeof(ScrBuf), rfi)) {
- X if (ScrBuf[0] == 'F' && strncmp(ScrBuf, "From ", 5) == 0)
- X strins(ScrBuf, " ");
- X fputs(ScrBuf, fo);
- X }
- X fclose(fo);
- X if (rfi != stdin)
- X fclose(rfi);
- X rfi = fopen(DataFile, "r");
- X fseek(rfi, pos, 0);
- X }
- X return(rfi);
- X}
- X
- XFILE *
- XOneMailToUUCP(toaddr, skipaddr, rfi)
- Xchar *toaddr;
- Xchar *skipaddr;
- XFILE *rfi;
- X{
- X static char ExecFile[128];
- X static char XExecFile[128];
- X static char CommandFile[128];
- X static char DataFile[128];
- X static char DestNode[256];
- X /*static char ToAddr[256];*/
- X FILE *fi;
- X int seq;
- X long pos;
- X short i;
- X short ai;
- X
- X /*
- X * If the destination node
- X */
- X
- X strcpy(DestNode, toaddr);
- X
- X ai = -1;
- X for (i = 0; DestNode[i]; ++i) {
- X /*
- X * Remember index for additional paths
- X */
- X
- X if (DestNode[i] == '!') {
- X DestNode[i] = 0;
- X ai = i + 1;
- X break;
- X }
- X
- X /*
- X * Cut off machine name at 7 chars and ignore any domain
- X * info.
- X */
- X
- X if (i == 7 || DestNode[i] == '.')
- X DestNode[i] = 0;
- X }
- X
- X Seq = seq = GetSequence(4);
- X
- X#define FOFF 8
- X
- X sprintf(ExecFile, "UUSPOOL:D.%sX%04d", DestNode, seq++);
- X sprintf(XExecFile, "UUSPOOL:X.%sX%04d", DestNode, seq++);
- X sprintf(CommandFile,"UUSPOOL:C.%sA%04d", DestNode, seq++);
- X sprintf(DataFile, "UUSPOOL:D.%sB%04d", DestNode, seq);
- X
- X LockFile(ExecFile);
- X LockFile(XExecFile);
- X LockFile(CommandFile);
- X LockFile(DataFile);
- X
- X /*
- X * Note, cannot run uuxqt from sendmail as uuxqt may call
- X * sendmail!
- X */
- X
- X if (strncmp(DestNode, NodeName, 7) == 0)
- X fi = fopen(XExecFile, "w");
- X else
- X fi = fopen(ExecFile, "w");
- X
- X if (fi == NULL)
- X goto fail;
- X
- X fprintf(fi, "U %s\n", UserName);
- X fprintf(fi, "F %s\n", DataFile + FOFF);
- X fprintf(fi, "I %s\n", DataFile + FOFF);
- X if (ai >= 0)
- X fprintf(fi, "C rmail %s!%s\n", DestNode + ai, skipaddr);
- X else
- X fprintf(fi, "C rmail %s\n", skipaddr);
- X fclose(fi);
- X
- X if (strncmp(DestNode, NodeName, 7)) {
- X fi = fopen(CommandFile, "w");
- X if (fi == NULL)
- X goto fail;
- X
- X fprintf(fi, "S %s %s %s - %s 0666\n", DataFile + FOFF, DataFile + FOFF, UserName, DataFile + FOFF);
- X fprintf(fi, "S %s %s %s - %s 0666\n", ExecFile + FOFF, XExecFile + FOFF, UserName, ExecFile + FOFF);
- X fclose(fi);
- X }
- X
- X fi = fopen(DataFile, "w");
- X if (fi == NULL)
- X goto fail;
- X
- X DumpHeaderInfo(fi, RCVR_UUCP, 1, 0);
- X pos = ftell(fi);
- X
- X if (ROpt) {
- X if (fgets(ScrBuf, sizeof(ScrBuf), rfi))
- X fputs(ScrBuf, fi);
- X }
- X while (fgets(ScrBuf, sizeof(ScrBuf), rfi)) {
- X if (ScrBuf[0] == 'F' && strncmp(ScrBuf, "From ", 5) == 0)
- X strins(ScrBuf, " ");
- X fputs(ScrBuf, fi);
- X }
- X fclose(fi);
- X if (rfi != stdin)
- X fclose(rfi);
- X fi = fopen(DataFile, "r");
- X fseek(fi, pos, 0);
- X return(fi);
- Xfail:
- X puts("Fail");
- X return(rfi);
- X}
- X
- Xvoid
- XDumpHeaderInfo(fi, rcvr, resend, local)
- XFILE *fi;
- X{
- X char *source;
- X time_t t;
- X
- X time(&t);
- X
- X /*
- X * Write header info
- X */
- X
- X if (rcvr == RCVR_UUCP)
- X source = "AmigaUUCP";
- X else
- X source = "Sendmail";
- X
- X if (ROpt) {
- X if (resend)
- X fprintf(fi, "%s %s remote from %s\n", FromLine, atime(&t), NodeName);
- X else
- X fprintf(fi, "%s %s\n", FromLine, atime(&t));
- X } else {
- X if (local)
- X fprintf(fi, "From %s %s\n", UserName, atime(&t));
- X else
- X fprintf(fi, "From %s %s remote from %s\n", UserName, atime(&t), NodeName);
- X }
- X fprintf(fi, "Received: by %s%s (0.44/0.44)\n\tid AA%05d; %s\n",
- X NodeName, DomainName, Seq, atime(&t)
- X );
- X DumpHeader(fi, "Received:", &RecvList);
- X if (ROpt == 0) {
- X time_t t2 = t + 3600 * GetHourOffset(TimeZoneName);
- X struct tm *ut;
- X
- X if (FindHeader("Date:") == NULL)
- X fprintf(fi, "Date: %s\n", atime(&t));
- X ut = localtime(&t2);
- X fprintf(fi, "Message-Id: <%02d%02d%02d%02d%02d.AA%05d@%s%s>\n",
- X ut->tm_year % 100, ut->tm_mon + 1, ut->tm_mday, ut->tm_hour, ut->tm_min,
- X Seq, NodeName, DomainName
- X );
- X }
- X
- X /*
- X * From:, To:, Cc:, Subject: (Bcc: never written to header),
- X * and any other header fields
- X */
- X
- X DumpHeader(fi, NULL, &HdrList);
- X DumpHeader(fi, "From:", &FromList);
- X DumpCombineHeader(fi, "To:", &ToList);
- X if (!EmptyList(&CcList))
- X DumpCombineHeader(fi, "Cc:", &CcList);
- X DumpHeader(fi, "Subject:", &SubjList);
- X
- X fprintf(fi, "\n");
- X}
- X
- Xvoid
- XDumpHeader(fi, field, list)
- XFILE *fi;
- Xchar *field;
- XLIST *list;
- X{
- X NODE *node;
- X
- X for (node = list->lh_Head; node != (NODE *)&list->lh_Tail; node = node->ln_Succ) {
- X if (field)
- X fprintf(fi, "%s %s\n", field, node->ln_Name);
- X else
- X fprintf(fi, "%s\n", node->ln_Name);
- X }
- X}
- X
- XNODE *
- XFindHeader(field)
- Xchar *field;
- X{
- X NODE *node;
- X short len = strlen(field);
- X
- X for (node = HdrList.lh_Head; node != (NODE *)&HdrList.lh_Tail; node = node->ln_Succ) {
- X if (strncmp(node->ln_Name, field, len) == 0)
- X return(node);
- X }
- X return(NULL);
- X}
- X
- Xvoid
- XDumpCombineHeader(fi, field, list)
- XFILE *fi;
- Xchar *field;
- XLIST *list;
- X{
- X NODE *node;
- X short ci = 0;
- X
- X fprintf(fi, "%s ", field);
- X for (node = list->lh_Head; node != (NODE *)&list->lh_Tail; node = node->ln_Succ) {
- X if (ci && ci + strlen(node->ln_Name) > 70) {
- X fprintf(fi, ",\n\t");
- X ci = 0;
- X }
- X if (ci)
- X fprintf(fi, ", ");
- X fprintf(fi, "%s", node->ln_Name);
- X ci += strlen(node->ln_Name) + 2;
- X }
- X fprintf(fi, "\n");
- X}
- X
- Xchar *
- Xatime(pt)
- Xtime_t *pt;
- X{
- X static char buf[40];
- X static char *mo[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- X "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
- X };
- X static char *dow[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
- X struct tm *ut = localtime(pt);
- X
- X sprintf(buf, "%s, %d %s %02d %02d:%02d:%02d %s",
- X dow[ut->tm_wday], ut->tm_mday, mo[ut->tm_mon],
- X ut->tm_year % 100, ut->tm_hour, ut->tm_min, ut->tm_sec,
- X TimeZoneName
- X );
- X return(buf);
- X}
- X
- XGetHourOffset(tz)
- Xchar *tz;
- X{
- X short i;
- X
- X static struct {
- X char *Name;
- X short Hours;
- X } TZAry[] = {
- X "GMT", 0,
- X "UT", 0,
- X "PST", 8,
- X "MST", 7,
- X "CST", 6,
- X "EST", 5,
- X "AST", 4,
- X "PDT", 7,
- X "MDT", 6,
- X "CDT", 5,
- X "EDT", 4,
- X "ADT", 3,
- X NULL, 0
- X };
- X for (i = 0; TZAry[i].Name; ++i) {
- X if (strncmp(tz, TZAry[i].Name, 3) == 0)
- X return((int)TZAry[i].Hours);
- X }
- X ulog(-1, "Unknown Timezone: %s", tz);
- X printf("Unknown Timezone: %s", tz);
- X return(6);
- X}
- X
- Xvoid
- XPostPend(str, frend)
- Xchar *str;
- X{
- X char *ptr;
- X if (frend) {
- X ptr = str + strlen(str);
- X while (ptr > str && *ptr != ' ' && *ptr != 9) {
- X if (*ptr == '\n')
- X *ptr = 0;
- X --ptr;
- X }
- X str = ptr + 1;
- X }
- X for (ptr = str; *ptr && *ptr != ' ' && *ptr != 9 && *ptr != '\n'; ++ptr);
- X if (frend)
- X strcpy(ptr, "!");
- X else
- X strcpy(ptr, "");
- X for (ptr = FromLine + 5; *ptr && *ptr != ' ' && *ptr != 9; ++ptr);
- X strins(ptr, str);
- X}
- X
- XEmptyList(list)
- XLIST *list;
- X{
- X if (list->lh_Head == (NODE *)&list->lh_Tail)
- X return(1);
- X return(0);
- X}
- X
- END_OF_FILE
- if test 22055 -ne `wc -c <'src/sendmail/sendmail.c'`; then
- echo shar: \"'src/sendmail/sendmail.c'\" unpacked with wrong size!
- fi
- # end of 'src/sendmail/sendmail.c'
- fi
- echo shar: End of archive 10 \(of 16\).
- cp /dev/null ark10isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 16 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- --
- Submissions to comp.sources.amiga and comp.binaries.amiga should be sent to:
- amiga@cs.odu.edu
- or amiga@xanth.cs.odu.edu ( obsolescent mailers may need this address )
- or ...!uunet!xanth!amiga ( very obsolescent mailers need this address )
-
- Comments, questions, and suggestions should be addressed to ``amiga-request''
- (please only use ``amiga'' for actual submissions) at the above addresses.
-